package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.outLink.domain.entity.OuterLinkConfigEntity;
import com.xbongbong.outLink.domain.entity.OuterLinkEntity;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.EsAliasEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.OuterLinkAddRemoveAttrEnum;
import com.xbongbong.paas.enums.OuterLinkFilterRemoveAttrEnum;
import com.xbongbong.paas.enums.OuterLinkShareRemoveAttrEnum;
import com.xbongbong.paas.feign.WorkOrderClient;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.VisibleRulePoJo;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.model.OuterLinkConfigModel;
import com.xbongbong.paas.model.OuterLinkModel;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.OutLinkFieldAttrEntity;
import com.xbongbong.paas.pojo.OutLinkSubFormPojo;
import com.xbongbong.paas.pojo.dto.FormDataGetDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkAddOutLinkExtensionDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkAdvancedGetDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkAdvancedSaveDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkAppearanceGetDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkAppearanceSaveDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkCloseOutLinkDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkConfigGetDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkDelOutLinkExtensionDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkDisplayGetDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkDisplaySaveDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkFilterGetDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkFilterSaveDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkGetOutLinkExtensionDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkPermissionGetDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkPermissionSaveDTO;
import com.xbongbong.paas.pojo.vo.FormDataGetVO;
import com.xbongbong.paas.service.OuterLinkConfigService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.OuterTokenUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.OutLinkErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.outLink.pojo.OutLinkAdvancedGetVO;
import com.xbongbong.pro.outLink.pojo.OutLinkDeleteVO;
import com.xbongbong.pro.outLink.pojo.OutLinkDisplayGetVO;
import com.xbongbong.pro.outLink.pojo.OutLinkExtensionAddVO;
import com.xbongbong.pro.outLink.pojo.OutLinkExtensionGetVO;
import com.xbongbong.pro.outLink.pojo.OutLinkFilterGetVO;
import com.xbongbong.pro.outLink.pojo.OutLinkPermissonGetVO;
import com.xbongbong.pro.outLink.pojo.OutLinkSettingGetVO;
import com.xbongbong.pro.outLink.pojo.OuterLinkAppearanceGetVO;
import com.xbongbong.pro.outLink.pojo.OuterLinkShareVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.domain.entity.WorkOrderTemplateEntity;
import com.xbongbong.saas.domain.entity.ext.WorkOrderExplainEntityExt;
import com.xbongbong.saas.domain.entity.ext.WorkOrderFormEntityExt;
import com.xbongbong.saas.enums.ForbiddenSettingEnum;
import com.xbongbong.saas.enums.OutLinkSettingTypeEnum;
import com.xbongbong.saas.enums.OuterLinkTypeEnum;
import com.xbongbong.saas.enums.ShowTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.help.SaasGetHelp;
import com.xbongbong.saas.model.PaasFormDataModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.saas.model.WorkOrderTemplateModel;
import com.xbongbong.saas.model.WorkReportModel;
import com.xbongbong.saas.script.help.InitExplainsHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author long.rao
 * @version v1.0
 * @date 2020/8/10 9:17
 * @since v1.0
 */
@Service("outerLinkConfigServiceImpl")
public class OuterLinkConfigServiceImpl implements OuterLinkConfigService {

    private static final Logger LOG = LoggerFactory.getLogger(OuterLinkConfigServiceImpl.class);

    private static final List<Integer> FILTER_ATTR = Arrays.asList(FieldTypeEnum.TEXT.getType(), FieldTypeEnum.NUM.getType(), FieldTypeEnum.DATETIME.getType(),
            FieldTypeEnum.RADIO_GROUP.getType(), FieldTypeEnum.COMBO.getType(), FieldTypeEnum.ADDRESS.getType(), FieldTypeEnum.SERIALNO.getType(), FieldTypeEnum.COMBO_CHECK.getType(), FieldTypeEnum.LABEL.getType());

    // 外链拓展目前最多拓展20个
    private static final int OUTLINK_EXTENSION_MAX = 20;

    @Resource
    private OuterLinkConfigModel outerLinkConfigModel;
    @Resource
    private OuterLinkModel outerLinkModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private ProBaseConfig proBaseConfig;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private WorkOrderTemplateModel workOrderTemplateModel;
    @Resource
    private PackageHelp packageHelp;
    @Resource
    private SaasGetHelp saasGetHelp;
    @Resource
    private PaasFormDataModel paasFormDataModel;
    @Resource
    private WorkReportModel workReportModel;
    @Resource
    private WorkOrderClient workOrderClient;


    @Override
    public OuterLinkAppearanceGetVO getAppearance(OuterLinkAppearanceGetDTO outerLinkAppearanceGetDTO) throws XbbException {
        OuterLinkAppearanceGetVO outerLinkAppearanceGetVO = new OuterLinkAppearanceGetVO();

        Long formId = outerLinkAppearanceGetDTO.getFormId();
        String corpid = outerLinkAppearanceGetDTO.getCorpid();
        Integer type = OuterLinkTypeEnum.WRITE.getCode();

        OuterLinkConfigEntity appearanceConfigEntity = getOuterLinkConfigEntities(corpid,formId,type,OutLinkSettingTypeEnum.APPEARANCE_SETTING.getCode());
        if (Objects.isNull(appearanceConfigEntity)) {
            JSONObject configInfo = new JSONObject();
            // 背景图片
            configInfo.put("bgUrl", "");
            // 背景颜色
            configInfo.put("bgColor", "rgba(255,255,255,1)");
            // 字体大小
            configInfo.put("fontSize", 28);
            // 字体颜色
            configInfo.put("fontColor", "rgba(0,0,0,1)");
            // 字体位置  11：左上 12：中上 13：右上  21：左中  22：居中  23：右中  31：左下  32：中下  33：右下
            configInfo.put("position", 11);
            outerLinkAppearanceGetVO.setConfigInfo(configInfo);
            outerLinkAppearanceGetVO.setThemeList(new JSONArray());
            outerLinkAppearanceGetVO.setThemeList(new JSONArray());
            outerLinkAppearanceGetVO.setInitFlag(BasicConstant.ZERO);
        } else {
            JSONObject templateInfo = appearanceConfigEntity.getTemplateInfo();
            JSONObject configInfo = templateInfo.getJSONObject("configInfo");
            outerLinkAppearanceGetVO.setConfigInfo(configInfo);

            JSONArray themeList = templateInfo.getJSONArray("themeList");
            outerLinkAppearanceGetVO.setThemeList(themeList);
            outerLinkAppearanceGetVO.setInitFlag(BasicConstant.ONE);
        }
        return outerLinkAppearanceGetVO;
    }

    @Override
    public BaseVO saveAppearance(OuterLinkAppearanceSaveDTO outerLinkAppearanceSaveDTO) throws XbbException {
        Long formId = outerLinkAppearanceSaveDTO.getFormId();
        String corpid = outerLinkAppearanceSaveDTO.getCorpid();
        Integer type = OuterLinkTypeEnum.WRITE.getCode();

        JSONArray themeList = outerLinkAppearanceSaveDTO.getThemeList();
        JSONObject configInfo = outerLinkAppearanceSaveDTO.getConfigInfo();

        JSONObject templateInfo = new JSONObject();
        OuterLinkConfigEntity appearanceConfigEntity = getOuterLinkConfigEntities(corpid,formId,type,OutLinkSettingTypeEnum.APPEARANCE_SETTING.getCode());
        try {
            if (Objects.isNull(appearanceConfigEntity)) {
                appearanceConfigEntity = new OuterLinkConfigEntity();
                appearanceConfigEntity.setType(type);
                appearanceConfigEntity.setFormId(formId);
                appearanceConfigEntity.setCorpid(corpid);
                appearanceConfigEntity.setDel(DelEnum.NORMAL.getDel());
                appearanceConfigEntity.setConfigType(OutLinkSettingTypeEnum.APPEARANCE_SETTING.getCode());

                templateInfo.put("themeList", themeList);
                templateInfo.put("configInfo", configInfo);
                appearanceConfigEntity.setTemplateInfo(templateInfo);
            } else {
                templateInfo.put("themeList", themeList);
                templateInfo.put("configInfo", configInfo);
                appearanceConfigEntity.setTemplateInfo(templateInfo);
            }
            outerLinkConfigModel.save(appearanceConfigEntity);
        } catch (XbbException e) {
            LOG.error("保存外链外观设置失败" + e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return new BaseVO();
    }

    /**
     * 获取权限设置
     * @param outerLinkPermissionGetDTO
     * @return
     * @throws XbbException
     */
    @Override
    public BaseVO getPermission(OuterLinkPermissionGetDTO outerLinkPermissionGetDTO) throws XbbException {
        OutLinkPermissonGetVO outLinkPermissonGetVO = new OutLinkPermissonGetVO();

        Integer businessType = outerLinkPermissionGetDTO.getBusinessType();
        Long formId = outerLinkPermissionGetDTO.getFormId();
        String corpid = outerLinkPermissionGetDTO.getCorpid();
        Integer type = outerLinkPermissionGetDTO.getType();

        List<FieldAttrEntity> filteredSpecialAttr = getOutLinkFieldList(corpid,formId,businessType, type, null);
        OuterLinkConfigEntity outerLinkConfigEntity = getOuterLinkConfigEntities(corpid,formId,type,OutLinkSettingTypeEnum.PERMISSION_SETTING.getCode());

        if (Objects.isNull(outerLinkConfigEntity)) {
            List<OutLinkFieldAttrEntity> explains = new ArrayList<>();
            for (int i = 0; i < filteredSpecialAttr.size(); i++) {
                FieldAttrEntity fieldAttrEntity = filteredSpecialAttr.get(i);
                OutLinkFieldAttrEntity outLinkFieldAttrEntity = new OutLinkFieldAttrEntity(fieldAttrEntity.getFieldType(),fieldAttrEntity.getAttrName(),fieldAttrEntity.getAttr(),fieldAttrEntity.getAttrName(),1,1,1,0);
                if (Objects.equals(type, OuterLinkTypeEnum.SHARE.getCode())) {
                    // 外链分享默认可见不可编辑
                    outLinkFieldAttrEntity.setEditable(BasicConstant.ZERO);
                }
                if (ExplainUtil.isSubFormNoSelectProduct(fieldAttrEntity.getFieldType())){
                    // 子表单
                    if(Objects.isNull(fieldAttrEntity.getSubForm())){
                        continue;
                    }
                    List<FieldAttrEntity> subExplainList = JSONObject.parseArray(JSON.toJSONString(fieldAttrEntity.getSubForm().getItems()), FieldAttrEntity.class);
                    List<OutLinkFieldAttrEntity> subFormFieldAttrList = new ArrayList<>();
                    if (Objects.nonNull(subExplainList)){
                        subExplainList.forEach(item -> {
                            OutLinkFieldAttrEntity subOutLinkFieldAttrEntity = new OutLinkFieldAttrEntity(item.getFieldType(),item.getAttrName(),item.getAttr(),item.getAttrName(),1,1,1,0);
                            if (Objects.equals(type, OuterLinkTypeEnum.SHARE.getCode())) {
                                // 外链分享默认可见不可编辑
                                subOutLinkFieldAttrEntity.setEditable(BasicConstant.ZERO);
                            }
                            subFormFieldAttrList.add(subOutLinkFieldAttrEntity);
                        });
                    }
                    OutLinkSubFormPojo subFormPoJo = new OutLinkSubFormPojo();
                    subFormPoJo.setItems(subFormFieldAttrList);
                    outLinkFieldAttrEntity.setSubForm(subFormPoJo);
                }
                explains.add(outLinkFieldAttrEntity);
            }
            outLinkPermissonGetVO.setExplainList(explains);
        } else {
            List<OutLinkFieldAttrEntity> outLinkFieldAttrEntityList = JSONArray.parseArray(outerLinkConfigEntity.getExplains(), OutLinkFieldAttrEntity.class);
            outLinkFieldAttrEntityList = syncOuterLinkField(filteredSpecialAttr, outLinkFieldAttrEntityList, OuterLinkTypeEnum.getByCode(type),OutLinkSettingTypeEnum.PERMISSION_SETTING);
            outLinkPermissonGetVO.setExplainList(outLinkFieldAttrEntityList);
        }
        return outLinkPermissonGetVO;
    }

    /**
     * 同步解释 包括新增和删除的解释
     * @param filteredSpecialAttr
     * @param outLinkFieldAttrEntityList
     * @return
     */
    @Override
    public List<OutLinkFieldAttrEntity> syncOuterLinkField(List<FieldAttrEntity> filteredSpecialAttr, List<OutLinkFieldAttrEntity> outLinkFieldAttrEntityList, OuterLinkTypeEnum type, OutLinkSettingTypeEnum configType) {
        /*Map<String, FieldAttrEntity> explainMap = new HashMap<>(filteredSpecialAttr.size());
        filteredSpecialAttr.forEach((item) -> {
            explainMap.put(item.getAttr(), item);
        });
        // 找出新增、删除的字段
        List<String> addFieldList = new ArrayList<>();
        Map<String, List<? extends OutLinkFieldAttrEntity>> addSubFieldMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<String> delFieldList = new ArrayList<>();
        Map<String, List<String>> delSubFieldMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);*/
        Map<String, OutLinkFieldAttrEntity> outLinkExplainMap = new HashMap<>(filteredSpecialAttr.size());
        Map<String, List<? extends OutLinkFieldAttrEntity>> outLinkSubExplainMap = new HashMap<>(filteredSpecialAttr.size());
        outLinkFieldAttrEntityList.forEach((item) -> {
            if (ExplainUtil.isSubFormNoSelectProduct(item.getFieldType())) {
                if(item.getSubForm()!=null){
                    outLinkSubExplainMap.put(item.getAttr(), item.getSubForm().getItems());
                }
            }
            outLinkExplainMap.put(item.getAttr(), item);
        });
        List<OutLinkFieldAttrEntity> newOuterLinkAttrs = new ArrayList<>(outLinkFieldAttrEntityList.size());
        Integer defaultEditable = 1;
        Integer defaultVisiable = 1;
        Integer defaultFilterable = 1;
        Integer defaultRename = 0;
        if (Objects.equals(type, OuterLinkTypeEnum.SHARE)) {
            defaultEditable = 0;
        }
        for (FieldAttrEntity fieldAttrEntity : filteredSpecialAttr) {
            String attr = fieldAttrEntity.getAttr();
            Integer fieldType = fieldAttrEntity.getFieldType();
            String attrName = fieldAttrEntity.getAttrName();
            OutLinkFieldAttrEntity outLinkFieldAttrEntity = outLinkExplainMap.get(attr);
            if (Objects.isNull(outLinkFieldAttrEntity)||
                    (ExplainUtil.isSubFormNoSelectProduct(outLinkFieldAttrEntity.getFieldType()) &&  outLinkFieldAttrEntity.getSubForm()==null)
            ) {
                outLinkFieldAttrEntity = new OutLinkFieldAttrEntity(fieldType,attrName,attr,attrName,defaultEditable,defaultVisiable,defaultFilterable,defaultRename);
                if (ExplainUtil.isSubFormNoSelectProduct(fieldAttrEntity.getFieldType())){
                    // 子表单
                    if(Objects.isNull(fieldAttrEntity.getSubForm())){
                        continue;
                    }
                    List<FieldAttrEntity> subExplainList = JSONObject.parseArray(JSON.toJSONString(fieldAttrEntity.getSubForm().getItems()), FieldAttrEntity.class);
                    List<OutLinkFieldAttrEntity> subFormFieldAttrList = new ArrayList<>();
                    if (Objects.nonNull(subExplainList)){
                        subExplainList.forEach(item -> {
                            OutLinkFieldAttrEntity subOutLinkFieldAttrEntity = new OutLinkFieldAttrEntity(item.getFieldType(),item.getAttrName(),item.getAttr(),item.getAttrName(),1,1,1,0);
                            if (Objects.equals(type, OuterLinkTypeEnum.SHARE.getCode())) {
                                // 外链分享默认可见不可编辑
                                subOutLinkFieldAttrEntity.setEditable(BasicConstant.ZERO);
                            }
                            subFormFieldAttrList.add(subOutLinkFieldAttrEntity);
                        });
                    }
                    OutLinkSubFormPojo subFormPoJo = new OutLinkSubFormPojo();
                    subFormPoJo.setItems(subFormFieldAttrList);
                    outLinkFieldAttrEntity.setSubForm(subFormPoJo);
                }
            } else {
                outLinkFieldAttrEntity.setAttrName(fieldAttrEntity.getAttrName());
                if (!Objects.equals(configType, OutLinkSettingTypeEnum.DISPLAY_SETTING.getCode())) {
                    // 外链显示设置这里，defaultName是用设置里配置的值处理的，其它的值只要用表单的值作为展示就行了
                    outLinkFieldAttrEntity.setDefaultName(fieldAttrEntity.getAttrName());
                }
                if (ExplainUtil.isSubFormNoSelectProduct(fieldAttrEntity.getFieldType())) {
                    if(outLinkFieldAttrEntity.getSubForm()==null||fieldAttrEntity.getSubForm()==null){
                        continue;
                    }
                    List<? extends OutLinkFieldAttrEntity> outerLinkItems = outLinkFieldAttrEntity.getSubForm().getItems();
                    Map<String, OutLinkFieldAttrEntity> subItemsMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    if (CollectionsUtil.isNotEmpty(outerLinkItems)) {
                        outerLinkItems.forEach(item -> subItemsMap.put(item.getAttr(), item));
                    }
                    List<? extends FieldAttrEntity> items = fieldAttrEntity.getSubForm().getItems();
                    if (CollectionsUtil.isNotEmpty(items)) {
                        List<OutLinkFieldAttrEntity> subItem = new ArrayList<>();
                        for (FieldAttrEntity item : items) {
                            String subAttr = item.getAttr();
                            String subAttrName = item.getAttrName();
                            OutLinkFieldAttrEntity subOuterLinkField = subItemsMap.get(subAttr);
                            if (Objects.isNull(subOuterLinkField)) {
                                subOuterLinkField = new OutLinkFieldAttrEntity(item.getFieldType(),subAttrName,subAttr,subAttrName,defaultEditable,defaultVisiable,defaultFilterable,defaultRename);
                            } else {
                                subOuterLinkField.setAttrName(subAttrName);
                                if (!Objects.equals(configType, OutLinkSettingTypeEnum.DISPLAY_SETTING.getCode())) {
                                    // 外链显示设置这里，defaultName是用设置里配置的值处理的，其它的值只要用表单的值作为展示就行了
                                    subOuterLinkField.setDefaultName(subAttrName);
                                }
                            }
                            subItem.add(subOuterLinkField);
                        }
                        outLinkFieldAttrEntity.getSubForm().setItems(subItem);
                    }
                }
            }
            newOuterLinkAttrs.add(outLinkFieldAttrEntity);
        }
        return newOuterLinkAttrs;
        /*for (int i = 0; i < filteredSpecialAttr.size(); i++) {
            String attr = filteredSpecialAttr.get(i).getAttr();
            if(!outLinkExplainMap.containsKey(attr)){
               addFieldList.add(attr);
            } else {
                FieldAttrEntity fieldAttrEntity = filteredSpecialAttr.get(i);
                if (ExplainUtil.isSubFormNoSelectProduct(fieldAttrEntity.getFieldType())){
                    List<? extends FieldAttrEntity> subFieldAttr = fieldAttrEntity.getSubForm().getItems();
                    List<? extends OutLinkFieldAttrEntity> subOuterFieldAttr = outLinkSubExplainMap.getOrDefault(attr, new ArrayList<>());
                    List<String> subOuterAttrs = new ArrayList<>();
                    for (OutLinkFieldAttrEntity entity : subOuterFieldAttr) {
                        subOuterAttrs.add(entity.getAttr());
                    }
                    List<String> subAttrs = new ArrayList<>();
                    List<OutLinkFieldAttrEntity> addSubAttr = new ArrayList<>();
                    for (int j = 0; j < subFieldAttr.size(); j++) {
                        FieldAttrEntity fieldEntity = subFieldAttr.get(j);
                        String fieldAttr = fieldEntity.getAttr();
                        subAttrs.add(fieldAttr);
                        if (!subOuterAttrs.contains(fieldAttr)) {
                            OutLinkFieldAttrEntity outLinkFieldAttr = new OutLinkFieldAttrEntity(fieldEntity.getFieldType(),fieldEntity.getAttrName(),fieldEntity.getAttr(),fieldEntity.getAttrName(),1,1,1,0);
                            addSubAttr.add(outLinkFieldAttr);
                        }
                    }
                    if (CollectionsUtil.isNotEmpty(addSubAttr)) {
                        addSubFieldMap.put(attr, addSubAttr);
                    }
                    List<String> delSubAttr = new ArrayList<>();
                    for (int j = 0; j < subOuterFieldAttr.size(); j++) {
                        OutLinkFieldAttrEntity fieldAttr = subOuterFieldAttr.get(j);
                        if (!subAttrs.contains(fieldAttr.getAttr())) {
                            delSubAttr.add(fieldAttr.getAttr());
                        }
                    }
                    if (CollectionsUtil.isNotEmpty(delSubAttr)) {
                        delSubFieldMap.put(attr, delSubAttr);
                    }
                }
            }
        }
        for (int i = 0; i < outLinkFieldAttrEntityList.size(); i++) {
            String attr = outLinkFieldAttrEntityList.get(i).getAttr();
            if (!explainMap.containsKey(attr)){
                delFieldList.add(attr);
            }
        }
        // 处理字段
        Iterator<OutLinkFieldAttrEntity> iterator = outLinkFieldAttrEntityList.iterator();
        while (iterator.hasNext()){
           if (delFieldList.contains(iterator.next().getAttr())){
               iterator.remove();
           }
        }
        if ((Objects.equals(OuterLinkTypeEnum.WRITE,type) && Objects.equals(OutLinkSettingTypeEnum.PERMISSION_SETTING,configType))
        || (Objects.equals(OuterLinkTypeEnum.SEARCH,type) && Objects.equals(OutLinkSettingTypeEnum.PERMISSION_SETTING,configType))){
            for (int i = 0; i < addFieldList.size(); i++) {
                String attr = addFieldList.get(i);
                FieldAttrEntity fieldAttrEntity = explainMap.getOrDefault(attr,new FieldAttrEntity());
                OutLinkFieldAttrEntity outLinkFieldAttrEntity = new OutLinkFieldAttrEntity(explainMap.get(attr).getFieldType(),explainMap.get(attr).getAttrName(),attr,explainMap.get(attr).getAttrName(),1,1,1,0);
                OutLinkSubFormPojo subForm = new OutLinkSubFormPojo();
                List<OutLinkFieldAttrEntity> items = new ArrayList<>();
                if (ExplainUtil.isSubFormNoSelectProduct(fieldAttrEntity.getFieldType())){
                    List<? extends FieldAttrEntity> subFieldAttr = fieldAttrEntity.getSubForm().getItems();
                    for (int j = 0; j < subFieldAttr.size(); j++) {
                        FieldAttrEntity fieldAttr = subFieldAttr.get(j);
                        OutLinkFieldAttrEntity outLinkFieldAttr = new OutLinkFieldAttrEntity(fieldAttr.getFieldType(),fieldAttr.getAttrName(),fieldAttr.getAttr(),fieldAttr.getAttrName(),1,1,1,0);
                        items.add(outLinkFieldAttr);
                    }
                    subForm.setItems(items);
                }
                outLinkFieldAttrEntity.setSubForm(subForm);
                outLinkFieldAttrEntityList.add(outLinkFieldAttrEntity);

            }
        } else if (Objects.equals(OuterLinkTypeEnum.SHARE,type) && Objects.equals(OutLinkSettingTypeEnum.PERMISSION_SETTING,configType)){
            for (int i = 0; i < addFieldList.size(); i++) {
                String attr = addFieldList.get(i);
                FieldAttrEntity fieldAttrEntity = explainMap.getOrDefault(attr,new FieldAttrEntity());
                OutLinkFieldAttrEntity outLinkFieldAttrEntity = new OutLinkFieldAttrEntity(explainMap.get(attr).getFieldType(),explainMap.get(attr).getAttrName(),attr,explainMap.get(attr).getAttrName(),0,1,1,0);
                OutLinkSubFormPojo subForm = new OutLinkSubFormPojo();
                List<OutLinkFieldAttrEntity> items = new ArrayList<>();
                if (ExplainUtil.isSubFormNoSelectProduct(fieldAttrEntity.getFieldType())){
                    List<? extends FieldAttrEntity> subFieldAttr = fieldAttrEntity.getSubForm().getItems();
                    for (int j = 0; j < subFieldAttr.size(); j++) {
                        FieldAttrEntity fieldAttr = subFieldAttr.get(j);
                        OutLinkFieldAttrEntity outLinkFieldAttr = new OutLinkFieldAttrEntity(fieldAttr.getFieldType(),fieldAttr.getAttrName(),fieldAttr.getAttr(),fieldAttr.getAttrName(),0,1,1,0);
                        if (Objects.equals(type, OuterLinkTypeEnum.SHARE.getCode())) {
                            // 外链分享默认可见不可编辑
                            outLinkFieldAttr.setEditable(BasicConstant.ZERO);
                        }
                        items.add(outLinkFieldAttr);
                    }
                    subForm.setItems(items);
                }
                if (Objects.equals(type, OuterLinkTypeEnum.SHARE.getCode())) {
                    // 外链分享默认可见不可编辑
                    outLinkFieldAttrEntity.setEditable(BasicConstant.ZERO);
                }
                outLinkFieldAttrEntity.setSubForm(subForm);
                outLinkFieldAttrEntityList.add(outLinkFieldAttrEntity);
            }
        } else {
            for (int i = 0; i < addFieldList.size(); i++) {
                String attr = addFieldList.get(i);
                FieldAttrEntity fieldAttrEntity = explainMap.getOrDefault(attr,new FieldAttrEntity());
                OutLinkFieldAttrEntity outLinkFieldAttrEntity = new OutLinkFieldAttrEntity(explainMap.get(attr).getFieldType(),explainMap.get(attr).getAttrName(),attr,explainMap.get(attr).getAttrName(),1,1,1,0);
                OutLinkSubFormPojo subForm = new OutLinkSubFormPojo();
                List<OutLinkFieldAttrEntity> items = new ArrayList<>();
                if (ExplainUtil.isSubFormNoSelectProduct(fieldAttrEntity.getFieldType())){
                    List<? extends FieldAttrEntity> subFieldAttr = fieldAttrEntity.getSubForm().getItems();
                    for (int j = 0; j < subFieldAttr.size(); j++) {
                        FieldAttrEntity fieldAttr = subFieldAttr.get(j);
                        OutLinkFieldAttrEntity outLinkFieldAttr = new OutLinkFieldAttrEntity(fieldAttr.getFieldType(),fieldAttr.getAttrName(),fieldAttr.getAttr(),fieldAttr.getAttrName(),1,1,1,0);
                        items.add(outLinkFieldAttr);
                    }
                    subForm.setItems(items);
                }
                outLinkFieldAttrEntity.setSubForm(subForm);
                outLinkFieldAttrEntityList.add(outLinkFieldAttrEntity);
            }
        }

        for (OutLinkFieldAttrEntity outLinkFieldAttrEntity : outLinkFieldAttrEntityList) {
            String attr = outLinkFieldAttrEntity.getAttr();
            if (ExplainUtil.isSubFormNoSelectProduct(outLinkFieldAttrEntity.getFieldType())) {
                List<? extends OutLinkFieldAttrEntity> items = outLinkFieldAttrEntity.getSubForm().getItems();
                List<String> delAttrs = delSubFieldMap.getOrDefault(attr, new ArrayList<>());
                List<OutLinkFieldAttrEntity> subItems = new ArrayList<>();
                Iterator<? extends OutLinkFieldAttrEntity> iterator1 = items.iterator();
                while (iterator1.hasNext()) {
                    OutLinkFieldAttrEntity next = iterator1.next();
                    if (delAttrs.contains(next.getAttr())) {
                        iterator1.remove();
                    } else {
                        subItems.add(next);
                    }
                }
                List<? extends OutLinkFieldAttrEntity> outLinkFieldAttrEntities = addSubFieldMap.get(attr);
                if (CollectionsUtil.isNotEmpty(outLinkFieldAttrEntities)) {
                    for (OutLinkFieldAttrEntity entity : outLinkFieldAttrEntities) {
                        if (Objects.equals(OuterLinkTypeEnum.SHARE,type)) {
                            // 外链分享默认可见不可编辑
                            entity.setEditable(0);
                        }
                        subItems.add(entity);
                    }
                }
                outLinkFieldAttrEntity.getSubForm().setItems(subItems);
            }
        }*/
    }

    /**
     * 权限设置保存
     * @param outerLinkPermissionSaveDTO
     * @return
     * @throws XbbException
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public BaseVO permissionSave(OuterLinkPermissionSaveDTO outerLinkPermissionSaveDTO) throws XbbException {
        BaseVO baseVO = new BaseVO();
        Integer type = outerLinkPermissionSaveDTO.getType();
        String corpid = outerLinkPermissionSaveDTO.getCorpid();
        Long formId = outerLinkPermissionSaveDTO.getFormId();

        List<OutLinkFieldAttrEntity> explainList = outerLinkPermissionSaveDTO.getExplainList();
        OuterLinkConfigEntity outerLinkConfigEntity = getOuterLinkConfigEntities(corpid,formId,type,OutLinkSettingTypeEnum.PERMISSION_SETTING.getCode());
        try{
            if (Objects.isNull(outerLinkConfigEntity)){
                OuterLinkConfigEntity entity = new OuterLinkConfigEntity();
                entity.setConfigType(1);
                entity.setCorpid(corpid);
                entity.setDel(0);
                entity.setFormId(formId);
                entity.setDefaultFormName("");
                entity.setType(type);
                entity.setExplains(JSONArray.toJSONString(explainList));
                entity.setSeniorInfo(new JSONObject());
                entity.setTemplateInfo(new JSONObject());
                outerLinkConfigModel.insert(entity);
            } else {
                outerLinkConfigEntity.setExplains(JSONArray.toJSONString(explainList));
                outerLinkConfigModel.update(outerLinkConfigEntity);
            }
        } catch (Exception e){
            LOG.error("权限更新失败" + e);
            throw new XbbException(ErrorCodeEnum.API_FAIL);
        }
        return baseVO;
    }

    /**
     * 显示设置保存
     * @param outerLinkDisplaySaveDTO
     * @return
     * @throws XbbException
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public BaseVO displaySave(OuterLinkDisplaySaveDTO outerLinkDisplaySaveDTO) throws XbbException {
        BaseVO baseVO = new BaseVO();
        Integer businessType = outerLinkDisplaySaveDTO.getBusinessType();
        String corpid = outerLinkDisplaySaveDTO.getCorpid();
        Long formId = outerLinkDisplaySaveDTO.getFormId();
        Integer type = outerLinkDisplaySaveDTO.getType();
        List<OutLinkFieldAttrEntity> frontFieldList = outerLinkDisplaySaveDTO.getDisplayFields();
        Map<String,String> renamedMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String,String> renamedSubMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (int i = 0; i < frontFieldList.size(); i++) {
            OutLinkFieldAttrEntity item = frontFieldList.get(i);
            renamedMap.put(item.getAttr(),item.getDefaultName());
            if (Objects.equals(item.getFieldType(), FieldTypeEnum.SUB_FORM.getType())
            || Objects.equals(item.getFieldType(), FieldTypeEnum.CONTACT_NUMBER.getType())){
                List<OutLinkFieldAttrEntity> subExplainList = JSONObject.parseArray(JSON.toJSONString(item.getSubForm().getItems()), OutLinkFieldAttrEntity.class);
                if (Objects.nonNull(subExplainList)){
                    for (int j = 0; j < subExplainList.size(); j++) {
                        OutLinkFieldAttrEntity entity = subExplainList.get(j);
                        renamedSubMap.put(item.getAttr() + "." + entity.getAttr(),entity.getDefaultName());
                    }
                }
            }
        }
        frontFieldList.forEach(item -> renamedMap.put(item.getAttr(),item.getDefaultName()));

        String defaultFormName = outerLinkDisplaySaveDTO.getDefaultFormName();

        OuterLinkConfigEntity outerLinkConfigEntity = getOuterLinkConfigEntities(corpid, formId, OuterLinkTypeEnum.getByCode(type).getCode(),OutLinkSettingTypeEnum.DISPLAY_SETTING.getCode());
        List<FieldAttrEntity> filteredSpecialAttr = getOutLinkFieldList(corpid,formId,businessType, type, null);
        List<OutLinkFieldAttrEntity> explains = new ArrayList<>();
        for (int i = 0; i < filteredSpecialAttr.size(); i++) {
            FieldAttrEntity item = filteredSpecialAttr.get(i);
            String attr = item.getAttr();
            OutLinkFieldAttrEntity outLinkFieldAttrEntity = new OutLinkFieldAttrEntity(item.getFieldType(),item.getAttrName(),attr,Objects.isNull(renamedMap.get(attr)) ? item.getAttrName() :  renamedMap.get(attr),1,1,1,Objects.isNull(renamedMap.get(attr)) ? 0 : 1);
            if (Objects.equals(item.getFieldType(), FieldTypeEnum.SUB_FORM.getType())
            || Objects.equals(item.getFieldType(), FieldTypeEnum.CONTACT_NUMBER.getType())){
                // 子表单
                List<? extends FieldAttrEntity> subExplainList = item.getSubForm().getItems();
                List<OutLinkFieldAttrEntity> subFormFieldAttrList = new ArrayList<>();
                if (Objects.nonNull(subExplainList)){
                    subExplainList.forEach(it -> {
                        OutLinkFieldAttrEntity subOutLinkFieldAttrEntity = new OutLinkFieldAttrEntity(it.getFieldType(),it.getAttrName(),it.getAttr(),Objects.isNull(renamedSubMap.get(attr + "." + it.getAttr())) ? it.getAttrName() :  renamedSubMap.get(attr + "." + it.getAttr()),1,1,1,Objects.isNull(renamedSubMap.get(attr + "." + it.getAttr())) ? 0 : 1);
                        subFormFieldAttrList.add(subOutLinkFieldAttrEntity);
                    });
                }
                OutLinkSubFormPojo subFormPoJo = new OutLinkSubFormPojo();
                subFormPoJo.setItems(subFormFieldAttrList);
                outLinkFieldAttrEntity.setSubForm(subFormPoJo);
            }
            explains.add(outLinkFieldAttrEntity);
        }
        try{
            if (Objects.isNull(outerLinkConfigEntity)){
                OuterLinkConfigEntity entity = new OuterLinkConfigEntity();
                entity.setConfigType(OutLinkSettingTypeEnum.DISPLAY_SETTING.getCode());
                entity.setCorpid(corpid);
                entity.setDel(DelEnum.NORMAL.getDel());
                entity.setFormId(formId);
                entity.setDefaultFormName(defaultFormName);
                entity.setType(type);
                entity.setExplains(JSONArray.toJSONString(explains));
                entity.setSeniorInfo(new JSONObject());
                entity.setTemplateInfo(new JSONObject());
                outerLinkConfigModel.insert(entity);
            } else {
                outerLinkConfigEntity.setExplains(JSONArray.toJSONString(explains));
                outerLinkConfigEntity.setDefaultFormName(defaultFormName);
                outerLinkConfigModel.update(outerLinkConfigEntity);
            }
        } catch (Exception e){
            LOG.error("筛选更新失败" + e);
            throw new XbbException(ErrorCodeEnum.API_FAIL);
        }
        return baseVO;
    }


    /**
     * 表单外链设置获取
     * @param outerLinkConfigGetDTO
     * @return
     * @throws XbbException
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public OutLinkSettingGetVO getOutLinkConfig(OuterLinkConfigGetDTO outerLinkConfigGetDTO) throws XbbException {
        OutLinkSettingGetVO outLinkSettingGetVO = new OutLinkSettingGetVO();
        Integer businessType = outerLinkConfigGetDTO.getBusinessType();
        String corpid = outerLinkConfigGetDTO.getCorpid();
        Long formId = outerLinkConfigGetDTO.getFormId();
        Integer isGet = outerLinkConfigGetDTO.getIsGet();

        List<Integer> enableList = outerLinkConfigGetDTO.getEnableList();
        JSONObject formAdd = new JSONObject();
        formAdd.put("enable",0);
        formAdd.put("url","");
        JSONObject formQuery = new JSONObject();
        formQuery.put("enable",0);
        formQuery.put("url","");
        JSONObject formShare = new JSONObject();
        formShare.put("enable",0);
        formShare.put("url","");
        // 已经有的记录 排除拓展字段
        List<OuterLinkEntity> outerLinkEntityList = getOuterLinkEntitiesExcludeExpandField(corpid, formId, null, null,null);
        List<Integer> alreadyGenerate = new ArrayList<>();
        if (Objects.nonNull(outerLinkEntityList)){
            for (int i = 0; i < outerLinkEntityList.size(); i++) {
                OuterLinkEntity item = outerLinkEntityList.get(i);
                Integer type = item.getType();
                Integer enable = item.getEnable();
                String token = item.getHashCode();
                String url = proBaseConfig.getWebFrontUrl() + "outer-form.html#/" + token;
                alreadyGenerate.add(type);
                if (Objects.equals(type, OuterLinkTypeEnum.WRITE.getCode())){
                    formAdd.put("enable",enable);
                    formAdd.put("url",url + "1");
                } else if (Objects.equals(type, OuterLinkTypeEnum.SEARCH.getCode())){
                    formQuery.put("enable",enable);
                    formQuery.put("url",url + "2");
                } else if (Objects.equals(type, OuterLinkTypeEnum.SHARE.getCode()) ){
                    formShare.put("enable",enable);
                }
            }
        }
        if (Objects.equals(isGet,0)){
            // 开启链接

            if (CollectionsUtil.isNotEmpty(enableList)){
                Integer type = enableList.get(0);
                List<OuterLinkEntity> outerLinks = getOuterLinkEntitiesExcludeExpandField(corpid, formId, type, null,null);
                String url = null;
                if (CollectionsUtil.isNotEmpty(outerLinks)){
                    for (int i = 0; i < outerLinks.size(); i++) {
                        OuterLinkEntity outerLinkEntity = outerLinks.get(i);
                        outerLinkEntity.setEnable(1);
                        String token = outerLinkEntity.getHashCode();
                        url =  proBaseConfig.getWebFrontUrl() + "outer-form.html#/" + token;
                        outerLinkModel.update(outerLinkEntity);
                    }
                }
                if (Objects.equals(type, OuterLinkTypeEnum.WRITE.getCode())){
                    formAdd.put("enable",1);
                    formAdd.put("url",url + "1");
                } else if (Objects.equals(type, OuterLinkTypeEnum.SEARCH.getCode())){
                    formQuery.put("enable",1);
                    formQuery.put("url",url + "2");
                } else if (Objects.equals(type, OuterLinkTypeEnum.SHARE.getCode()) ){
                    formShare.put("enable",1);
                }
            }
            // 生成链接
            enableList.removeAll(alreadyGenerate);
            for (int i = 0; i < enableList.size(); i++) {
                Integer type = enableList.get(i);
                String token = OuterTokenUtil.getEncryptToken(formId,corpid,businessType,type,"");
                String url = proBaseConfig.getWebFrontUrl() + "outer-form.html#/" +token;
                OuterLinkEntity outerLinkEntity = new OuterLinkEntity();
                outerLinkEntity.setCorpid(corpid);
                outerLinkEntity.setFormId(formId);
                outerLinkEntity.setBusinessType(businessType);
                outerLinkEntity.setDel(0);
                outerLinkEntity.setEnable(1);
                if (Objects.equals(type, OuterLinkTypeEnum.SHARE.getCode())) {
                    // 外链分享需要用到dataId,所以默认为0
                    outerLinkEntity.setDataId(0L);
                }
                outerLinkEntity.setHashCode(token);
                outerLinkEntity.setType(type);
                outerLinkEntity.setBusinessType(businessType);
                outerLinkModel.insert(outerLinkEntity);
                if (Objects.equals(type, OuterLinkTypeEnum.WRITE.getCode())){
                    formAdd.put("enable",1);
                    formAdd.put("url",url + "1");
                } else if (Objects.equals(type, OuterLinkTypeEnum.SEARCH.getCode())){
                    formQuery.put("enable",1);
                    formQuery.put("url",url + "2");
                } else if (Objects.equals(type, OuterLinkTypeEnum.SHARE.getCode())){
                    formShare.put("enable",1);
                }
            }

        }
        outLinkSettingGetVO.setFormId(formId);
        outLinkSettingGetVO.setFormAdd(formAdd);
        outLinkSettingGetVO.setFormQuery(formQuery);
        outLinkSettingGetVO.setFormShare(formShare);
        notSupportOutLink(outLinkSettingGetVO,businessType,outerLinkConfigGetDTO);
        return outLinkSettingGetVO;
    }

    /**
     * 暂不支持外链的表单
     * @param outLinkSettingGetVO
     * @param businessType
     */
    private void notSupportOutLink(OutLinkSettingGetVO outLinkSettingGetVO, Integer businessType,OuterLinkConfigGetDTO outerLinkConfigGetDTO) throws XbbException {
        // 不支持外链填写的业务
        List<Integer> notSupportOutLinkAdd = Arrays.asList(XbbRefTypeEnum.PAYMENT.getCode(),
                XbbRefTypeEnum.PAY_PLAN.getCode(),
                XbbRefTypeEnum.CONTRACT.getCode(),
                XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(),
                XbbRefTypeEnum.COMMUNICATE_PLAN.getCode(),
                XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode(),
                XbbRefTypeEnum.QUOTATION.getCode(),
                XbbRefTypeEnum.REFUND.getCode(),
                XbbRefTypeEnum.WORK_REPORT.getCode(),
                XbbRefTypeEnum.WORKREPORT_DAILY.getCode(),
                XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode(),
                XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode(),
                XbbRefTypeEnum.SUPPLIER_CONTACT.getCode(),
                XbbRefTypeEnum.SUPPLIER_COMMUNICATE.getCode(),
                XbbRefTypeEnum.SUPPLIER.getCode(),
                XbbRefTypeEnum.RETURNED_PURCHASE.getCode(),
                XbbRefTypeEnum.BOM_BILL.getCode(),
                XbbRefTypeEnum.PRODUCTION_ORDER.getCode(),
                XbbRefTypeEnum.INVENTORY.getCode(),
                XbbRefTypeEnum.WAREHOUSE.getCode(),
                XbbRefTypeEnum.ASSEMBLE.getCode(),
                XbbRefTypeEnum.TRANSFER.getCode(),
                XbbRefTypeEnum.PURCHASE_INSTOCK.getCode(),
                XbbRefTypeEnum.REFUND_INSTOCK.getCode(),
                XbbRefTypeEnum.OTHER_INSTOCK.getCode(),
                XbbRefTypeEnum.PRODUCTION_INSTOCK.getCode(),
                XbbRefTypeEnum.RETURNED_MATERIEL_INSTOCK.getCode(),
                XbbRefTypeEnum.OUTSTOCK.getCode(),
                XbbRefTypeEnum.OTHER_OUTSTOCK.getCode(),
                XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode(),
                XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode(),
                XbbRefTypeEnum.PRODUCTION_MATERIEL_OUTSTOCK.getCode(),
                XbbRefTypeEnum.WORK_ORDER_OUTSTOCK.getCode(),
                XbbRefTypeEnum.PAYMENT_SHEET.getCode(),
                XbbRefTypeEnum.PURCHASE_INVOICE.getCode(),
                XbbRefTypeEnum.PURCHASE.getCode(),
                XbbRefTypeEnum.PAY_SHEET.getCode(),
                XbbRefTypeEnum.CONTACT.getCode(),
                XbbRefTypeEnum.INVOICE.getCode(),
                XbbRefTypeEnum.PRODUCT.getCode(),
                XbbRefTypeEnum.RECEIPT_ORDER.getCode(),
                XbbRefTypeEnum.SIGNIN.getCode()
                );
        // 不支持外链查询的业务 客户，合同，联系人
        List<Integer> notSupportOutLinkQuery = Arrays.asList(
                XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(),
                XbbRefTypeEnum.CONTRACT.getCode(),
                XbbRefTypeEnum.SIGNIN.getCode(),
                XbbRefTypeEnum.CONTACT.getCode());

        // 不支持外链分享的业务 签到
        List<Integer> notSupportOutLinkShare = Arrays.asList(
                XbbRefTypeEnum.SIGNIN.getCode());

        outLinkSettingGetVO.getFormAdd().put("show",true);
        outLinkSettingGetVO.getFormQuery().put("show",true);
        outLinkSettingGetVO.getFormShare().put("show",true);

        if (notSupportOutLinkAdd.contains(businessType)) {
            outLinkSettingGetVO.getFormAdd().put("show", false);
        }
        if (notSupportOutLinkQuery.contains(businessType)) {
            outLinkSettingGetVO.getFormQuery().put("show", false);
        }
        if (notSupportOutLinkShare.contains(businessType)) {
            outLinkSettingGetVO.getFormShare().put("show", false);
        }
        // 特殊处理工单
        if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
            boolean isFree;
            WorkOrderExplainEntityExt workOrderExplainEntityExt = workOrderExplainModel.getByFormId(outerLinkConfigGetDTO.getFormId(), outerLinkConfigGetDTO.getCorpid());
            if (workOrderExplainEntityExt == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            WorkOrderFormEntityExt workOrderEntity = workOrderFormModel.getByKey(outerLinkConfigGetDTO.getFormId(), outerLinkConfigGetDTO.getCorpid());
            WorkOrderTemplateEntity workOrderTemplateEntity = workOrderTemplateModel.getBykey(workOrderEntity.getTemplateId(), outerLinkConfigGetDTO.getCorpid());
            isFree = Objects.equals(workOrderTemplateEntity.getIsFree(), 1);
            if (isFree){
                outLinkSettingGetVO.getFormAdd().put("show",false);
            }
        }
    }

    /**
     * 筛选设置保存
     * @param outerLinkFilterSaveDTO
     * @return
     * @throws XbbException
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public BaseVO filterSave(OuterLinkFilterSaveDTO outerLinkFilterSaveDTO) throws XbbException {
        BaseVO baseVO = new BaseVO();
        List<String>  screenList = outerLinkFilterSaveDTO.getScreenList();
        Integer businessType = outerLinkFilterSaveDTO.getBusinessType();
        String corpid = outerLinkFilterSaveDTO.getCorpid();
        Long formId = outerLinkFilterSaveDTO.getFormId();
        OuterLinkConfigEntity outerLinkConfigEntity = getOuterLinkConfigEntities(corpid, formId, OuterLinkTypeEnum.SEARCH.getCode(),OutLinkSettingTypeEnum.FILTER_SETTING.getCode());
        List<FieldAttrEntity> filteredSpecialAttr = getOutLinkFieldList(corpid,formId,businessType, OuterLinkTypeEnum.SEARCH.getCode(), BasicConstant.ONE);

        List<OutLinkFieldAttrEntity> explains = new ArrayList<>();
        for (int i = 0; i < filteredSpecialAttr.size(); i++) {
            FieldAttrEntity item = filteredSpecialAttr.get(i);
            OutLinkFieldAttrEntity outLinkFieldAttrEntity = new OutLinkFieldAttrEntity(item.getFieldType(),item.getAttrName(),item.getAttr(),item.getAttrName(),1,1,1,0);
            if (!screenList.contains(item.getAttr())){
                outLinkFieldAttrEntity.setFilterable(0);
            }
            explains.add(outLinkFieldAttrEntity);
        }
        try{
            if (Objects.isNull(outerLinkConfigEntity)){
                OuterLinkConfigEntity entity = new OuterLinkConfigEntity();
                entity.setConfigType(OutLinkSettingTypeEnum.FILTER_SETTING.getCode());
                entity.setCorpid(corpid);
                entity.setDel(DelEnum.NORMAL.getDel());
                entity.setFormId(formId);
                entity.setDefaultFormName("");
                entity.setType(OuterLinkTypeEnum.SEARCH.getCode());
                entity.setExplains(JSONArray.toJSONString(explains));
                entity.setSeniorInfo(new JSONObject());
                entity.setTemplateInfo(new JSONObject());
                outerLinkConfigModel.insert(entity);
            } else {
                outerLinkConfigEntity.setExplains(JSONArray.toJSONString(explains));
                outerLinkConfigModel.update(outerLinkConfigEntity);
            }
        } catch (Exception e){
            LOG.error("筛选更新失败" + e);
            throw new XbbException(ErrorCodeEnum.API_FAIL);
        }
        return baseVO;
    }

    /**
     * 高级设置保存
     * @param outerLinkAdvancedSaveDTO
     * @return
     * @throws XbbException
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public BaseVO advancedSave(OuterLinkAdvancedSaveDTO outerLinkAdvancedSaveDTO) throws XbbException {
        BaseVO baseVO = new BaseVO();
        Integer businessType = outerLinkAdvancedSaveDTO.getBusinessType();
        Long formId = outerLinkAdvancedSaveDTO.getFormId();
        String corpid = outerLinkAdvancedSaveDTO.getCorpid();
        JSONObject seniorInfoPojo = outerLinkAdvancedSaveDTO.getSetting();
        OuterLinkConfigEntity outerLinkConfigEntity = getOuterLinkConfigEntities(corpid,formId, OuterLinkTypeEnum.WRITE.getCode(),OutLinkSettingTypeEnum.ADVANCED_SETTING.getCode());
        try{
            if (Objects.isNull(outerLinkConfigEntity)){
                OuterLinkConfigEntity entity = new OuterLinkConfigEntity();
                entity.setDefaultFormName("");
                entity.setTemplateInfo(new JSONObject());
                entity.setType(OuterLinkTypeEnum.WRITE.getCode());
                entity.setConfigType(OutLinkSettingTypeEnum.ADVANCED_SETTING.getCode());
                entity.setSeniorInfo(seniorInfoPojo);
                entity.setExplains("");
                entity.setFormId(formId);
                entity.setCorpid(corpid);
                outerLinkConfigModel.insert(entity);
            } else {
                outerLinkConfigEntity.setSeniorInfo(seniorInfoPojo);
                outerLinkConfigModel.update(outerLinkConfigEntity);
            }
        } catch (Exception e){
            LOG.error("高级设置更新失败",e);
            throw  new XbbException(ErrorCodeEnum.API_FAIL);
        }

        return baseVO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public OuterLinkShareVO shareCopy(OuterLinkDTO outerLinkDTO) throws XbbException {
        OuterLinkShareVO outerLinkShareVO = new OuterLinkShareVO();
        Integer businessType = outerLinkDTO.getBusinessType();
        String corpid = outerLinkDTO.getCorpid();
        Long formId ;
        Long dataId = outerLinkDTO.getDataId();
        //校验套餐类型
        Integer feeType = packageHelp.getFeeType(corpid);
        if (Objects.equals(feeType,PackageTypeEnum.STANDARD.getType())){
            throw new XbbException(OutLinkErrorCodeEnum.API_ERROR_405014);
        }
        if (Objects.isNull(dataId)) {
            throw new XbbException(OutLinkErrorCodeEnum.API_ERROR_405004);
        }
        Integer type = OuterLinkTypeEnum.SHARE.getCode();

        PaasFormDataEntityExt paasFormDataEntityExt;
        if ( Objects.equals(businessType,0) ) {
            paasFormDataEntityExt = paasFormDataModel.getByKey(dataId,corpid);
        } else if (Objects.equals(businessType, XbbRefTypeEnum.WORK_REPORT.getCode())) {
            paasFormDataEntityExt = workReportModel.getByKey(dataId,corpid);
        } else if (Objects.equals(businessType, XbbRefTypeEnum.RECEIPT_ORDER.getCode())) {
            String result;
            try {
                FormDataGetDTO formDataGetDTO = new FormDataGetDTO();
                BeanUtils.copyProperties(outerLinkDTO, formDataGetDTO);
                formDataGetDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                result = workOrderClient.getFormData(formDataGetDTO, LocaleContextHolder.getLocale().toString());
            } catch (Exception e) {
                LOG.error("获取表单数据报错", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, I18nStringConstant.FORM_DATA_ERROR);
            }
            JSONObject resultObj = JsonHelperUtil.parseObject(result);
            if (ErrorCodeEnum.API_SUCCESS.getCode() != (int)resultObj.get(StringConstant.CODE)) {
                throw new XbbException(resultObj.getIntValue(StringConstant.CODE),resultObj.getString(StringConstant.KEY_ERROR_MSG));
            }
            FormDataGetVO formDataGetVO = JsonHelperUtil.parseObject(resultObj.getString("result"),FormDataGetVO.class);
            paasFormDataEntityExt = formDataGetVO.getFormList();
        } else {
            paasFormDataEntityExt = saasGetHelp.getFormData(dataId,corpid,businessType);
        }

        if (Objects.isNull(paasFormDataEntityExt)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404);
        }

        formId = paasFormDataEntityExt.getFormId();
        OuterLinkEntity outerLink = outerLinkModel.getOuterLink(formId, type, corpid, 0L);
        if (Objects.nonNull(outerLink)) {
            if (!Objects.equals(outerLink.getEnable(), BasicConstant.ONE)) {
                throw new XbbException(OutLinkErrorCodeEnum.API_ERROR_405003);
            }
        } else {
            throw new XbbException(OutLinkErrorCodeEnum.API_ERROR_405003);
        }

        if (Objects.equals(businessType, XbbRefTypeEnum.WORK_REPORT.getCode())) {
            // 工作报告的businessType前端传来2101，没有具体到日、周、月，所以这里手动转一下
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, corpid);
            param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            param.put("formId", formId);
            List<PaasFormEntityExt> entitys = paasFormModel.findEntitys(param);
            if (CollectionsUtil.isEmpty(entitys)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            businessType = entitys.get(0).getBusinessType();
        }

        String createrId = "";
        if ( Objects.nonNull(paasFormDataEntityExt) ) {
            createrId = paasFormDataEntityExt.getCreatorId();
        }
        String token = "";
        OuterLinkEntity outerLinkEntity = outerLinkModel.getOuterLink(formId, type, corpid, dataId);
        if (Objects.nonNull(outerLinkEntity)) {
            token = outerLinkEntity.getHashCode();
        } else {
            try {
                token = OuterTokenUtil.getEncryptToken(formId, corpid, businessType, type, dataId, createrId);
                outerLinkEntity = new OuterLinkEntity();
                outerLinkEntity.setCorpid(corpid);
                outerLinkEntity.setFormId(formId);
                outerLinkEntity.setDel(0);
                outerLinkEntity.setEnable(1);
                outerLinkEntity.setHashCode(token);
                outerLinkEntity.setDataId(dataId);
                outerLinkEntity.setType(type);
                outerLinkEntity.setBusinessType(businessType);
                outerLinkModel.insert(outerLinkEntity);
            } catch (XbbException e) {
                LOG.error("OuterLinkConfigServiceImpl.shareCopy失败:原因" + e.getMsg());
                throw new XbbException(ErrorCodeEnum.API_FAIL);
            }
        }
        String url = proBaseConfig.getWebFrontUrl() + "outer-form.html#/" + token + "3";
        outerLinkShareVO.setUrl(url);
        return outerLinkShareVO;
    }

    @Override
    public BaseVO closeOutLink(OuterLinkCloseOutLinkDTO outerLinkCloseOutLinkDTO) throws XbbException {
        OutLinkDeleteVO outLinkDeleteVO = new OutLinkDeleteVO();
        Integer businessType = outerLinkCloseOutLinkDTO.getBusinessType();
        Long formId = outerLinkCloseOutLinkDTO.getFormId();
        String corpid = outerLinkCloseOutLinkDTO.getCorpid();
        Integer type = outerLinkCloseOutLinkDTO.getDisable();
//        OuterLinkConfigEntity outerLinkConfigEntity = getOuterLinkConfigEntities(corpid,formId, type,null);
        List<OuterLinkEntity> OuterLinkEntities = getOuterLinkEntities(corpid,formId,type,null,null,DelEnum.NORMAL.getDel());
        if (CollectionsUtil.isNotEmpty( OuterLinkEntities)){
            try{
                for (int i = 0; i < OuterLinkEntities.size() ; i++) {
                    OuterLinkEntity outerLinkEntity = OuterLinkEntities.get(i);
                    outerLinkEntity.setEnable(0);
//            outerLinkConfigEntity.setDel(DelEnum.DELETE.getDel());
//            outerLinkConfigModel.update(outerLinkConfigEntity);
                    outerLinkModel.update(outerLinkEntity);
                }
            } catch (Exception e){
                LOG.error("关闭外链出错",e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            return outLinkDeleteVO;
        }
        return null;
    }

    /**
     * 添加外链拓展字段
     * @param outerLinkAddOutLinkExtensionDTO
     * @return
     * @throws XbbException
     */
    @Override
    public OutLinkExtensionAddVO addOutLinkExtension(OuterLinkAddOutLinkExtensionDTO outerLinkAddOutLinkExtensionDTO) throws XbbException {
        OutLinkExtensionAddVO outLinkExtensionAddVO = new OutLinkExtensionAddVO();
        JSONObject extension = new JSONObject();
        Integer businessType = outerLinkAddOutLinkExtensionDTO.getBusinessType();
        String corpid = outerLinkAddOutLinkExtensionDTO.getCorpid();
        Long formId = outerLinkAddOutLinkExtensionDTO.getFormId();
        String extenedField = outerLinkAddOutLinkExtensionDTO.getExtenedField();
        Integer type = OuterLinkTypeEnum.WRITE.getCode();

        // 外链删除与否不影响
        String extensionAttr = null;
        // 之前有没有拓展过
        boolean flag = false;

        // 目前已经拓展了多少个外链 已经删除的外链不计入其内
        int count = 0;
        // 是否有重复的外链值 比如两个抖音
        boolean repeat = false;

        List<OuterLinkEntity> outerLinkEntityList = getOuterLinkEntities(corpid, formId, OuterLinkTypeEnum.WRITE.getCode(), null,null,DelEnum.NORMAL.getDel());
        if (CollectionsUtil.isNotEmpty(outerLinkEntityList)){
            for (int i = 0; i < outerLinkEntityList.size(); i++) {
                OuterLinkEntity outerLinkEntity = outerLinkEntityList.get(i);
                if (Objects.equals(outerLinkEntity.getExpandField(),extenedField)){
                    repeat = true;
                }
                if (Objects.isNull(outerLinkEntity.getAttr())){
                    continue;
                }
                count ++;
            }
        }

        List<OuterLinkEntity> outerLinkEntities = getOuterLinkEntities(corpid, formId, OuterLinkTypeEnum.WRITE.getCode(), null,null,null);
        if (CollectionsUtil.isNotEmpty(outerLinkEntities)){
            for (int i = 0; i < outerLinkEntities.size(); i++) {
                OuterLinkEntity outerLink = outerLinkEntities.get(i);
                if (Objects.isNull(outerLink.getAttr())){
                    continue;
                }
                flag = true;
                extensionAttr = outerLink.getAttr();
            }
        }

        if (count >= OUTLINK_EXTENSION_MAX){
            throw new XbbException(OutLinkErrorCodeEnum.API_ERROR_405011);
        }
        if (repeat){
            throw new XbbException(OutLinkErrorCodeEnum.API_ERROR_405012);
        }
        if(StringUtil.isNotEmpty(extenedField) && extenedField.length() > 20){
            throw new XbbException(OutLinkErrorCodeEnum.API_ERROR_405013);
        }
        if (flag){
            // attr 若outlinkyouattr直接用 没有动态生成
            try {
                String token = OuterTokenUtil.getEncryptToken(formId,corpid,businessType,type,extenedField);
                String url = proBaseConfig.getWebFrontUrl() + "outer-form.html#/" +token+ "1";
                OuterLinkEntity outerLinkEntity = new OuterLinkEntity();
                outerLinkEntity.setCorpid(corpid);
                outerLinkEntity.setFormId(formId);
                outerLinkEntity.setBusinessType(businessType);
                outerLinkEntity.setDel(0);
                outerLinkEntity.setEnable(1);
                outerLinkEntity.setAttr(extensionAttr);
                if (Objects.equals(type, OuterLinkTypeEnum.SHARE.getCode())) {
                    // 外链分享需要用到dataId,所以默认为0
                    outerLinkEntity.setDataId(0L);
                }
                outerLinkEntity.setHashCode(token);
                outerLinkEntity.setType(type);
                outerLinkEntity.setBusinessType(businessType);
                outerLinkEntity.setExpandField(extenedField);
                outerLinkModel.insert(outerLinkEntity);
                extension.put("field",extenedField);
                extension.put("url",url);
                extension.put("id",outerLinkEntity.getId());
                outLinkExtensionAddVO.setExtension(extension);
            } catch (Exception e){
                LOG.error("添加外链拓展失败",e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
        } else {
            // 获取拓展字段的attr并outlink插一条记录 attr
            PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                //工单
                WorkOrderExplainEntity workOrderExplainEntity = workOrderExplainModel.getByFormId(formId, corpid);
                if (Objects.isNull(workOrderExplainEntity)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                BeanUtil.copyProperties(workOrderExplainEntity, paasFormExplainEntity);
            } else {
                //其他
                paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
                if (Objects.isNull(paasFormExplainEntity)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
            }
            List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            // 有没有空位 如果有空位可以存放 则返回true 没有空位可以存放 则返回false
            boolean hasEmpty = false;
            for (int i = 1; i <= EsAliasEnum.TEXT.getSaasMax(); i++) {
                // text_i有没有被占用
                boolean occupation = false;
                for (int j = 0; j < explainList.size(); j++) {
                    FieldAttrEntity fieldAttrEntity = explainList.get(j);
                    if (("text_" + i).equals(fieldAttrEntity.getAttr())){
                        occupation = true;
                    }
                }
                if (occupation){
                    continue;
                } else {
                    hasEmpty = true;
                    extensionAttr = "text_" + i;
                    break;
                }
            }
            if (!hasEmpty){
                throw new XbbException(OutLinkErrorCodeEnum.API_ERROR_405008);
            }
            FieldAttrEntity fieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
            fieldAttrEntity.setAttr(extensionAttr);
            fieldAttrEntity.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.OUT_EXTENSION));
            fieldAttrEntity.setFieldType(FieldTypeEnum.TEXT.getType());
            fieldAttrEntity.setVisible(1);
            fieldAttrEntity.setSaasAttr("extensionField");
            fieldAttrEntity.setEditable(0);
            fieldAttrEntity.setShowType(ShowTypeEnum.LIST_DETAIL.getCode());
            fieldAttrEntity.setShowRemove(0);
            fieldAttrEntity.setIsForbidden(1);
            fieldAttrEntity.setIsRedundant(0);
            fieldAttrEntity.setShowEditable(0);
            fieldAttrEntity.setSort(explainList.size());
            fieldAttrEntity.setVisibleScopeRule(new VisibleRulePoJo());
            fieldAttrEntity.setAttrType(FieldTypeEnum.TEXT.getEsalias());
            fieldAttrEntity.setForbiddenSettingList(Arrays.asList(ForbiddenSettingEnum.DISABLE_DEFAULT.getAlias(),ForbiddenSettingEnum.DISABLE_RULE.getAlias(),ForbiddenSettingEnum.DISABLE_TYPE.getAlias()));
            explainList.add(fieldAttrEntity);
            paasFormExplainEntity.setExplains(JSONObject.toJSONString(explainList));
            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                //工单
                WorkOrderExplainEntity workOrderExplainEntity = new WorkOrderExplainEntity();
                BeanUtil.copyProperties(paasFormExplainEntity, workOrderExplainEntity);
                workOrderExplainModel.update(workOrderExplainEntity);
            }else {
                // 其他
                paasFormExplainModel.update(paasFormExplainEntity);
            }

            // 拓展字段重复

            try {
                String token = OuterTokenUtil.getEncryptToken(formId,corpid,businessType,type,extenedField);
                String url = proBaseConfig.getWebFrontUrl() + "outer-form.html#/" +token+ "1";
                OuterLinkEntity outerLinkEntity = new OuterLinkEntity();
                outerLinkEntity.setCorpid(corpid);
                outerLinkEntity.setFormId(formId);
                outerLinkEntity.setBusinessType(businessType);
                outerLinkEntity.setDel(0);
                outerLinkEntity.setEnable(1);
                outerLinkEntity.setAttr(extensionAttr);
                if (Objects.equals(type, OuterLinkTypeEnum.SHARE.getCode())) {
                    // 外链分享需要用到dataId,所以默认为0
                    outerLinkEntity.setDataId(0L);
                }
                outerLinkEntity.setHashCode(token);
                outerLinkEntity.setType(type);
                outerLinkEntity.setBusinessType(businessType);
                outerLinkEntity.setExpandField(extenedField);
                outerLinkModel.insert(outerLinkEntity);
                extension.put("field",extenedField);
                extension.put("url",url);
                extension.put("id",outerLinkEntity.getId());
                outLinkExtensionAddVO.setExtension(extension);
            } catch (Exception e){
                LOG.error("添加外链拓展失败",e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
        }

        return outLinkExtensionAddVO;
    }

    /**
     * 删除外链拓展字段
     * @param outerLinkDelOutLinkExtensionDTO
     * @return
     * @throws XbbException
     */
    @Override
    public BaseVO delOutLinkExtension(OuterLinkDelOutLinkExtensionDTO outerLinkDelOutLinkExtensionDTO) throws XbbException {
        BaseVO baseVO = new BaseVO();
        Long id = outerLinkDelOutLinkExtensionDTO.getId();
        try{
            outerLinkModel.deleteByKey(id);
        } catch (Exception e){
            LOG.error("删除拓展链接 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return baseVO;
    }

    @Override
    public OutLinkExtensionGetVO getOutLinkExtension(OuterLinkGetOutLinkExtensionDTO outerLinkGetOutLinkExtensionDTO) throws XbbException {
        OutLinkExtensionGetVO outLinkExtensionGetVO = new OutLinkExtensionGetVO();
        JSONArray extension = new JSONArray();
        Long formId = outerLinkGetOutLinkExtensionDTO.getFormId();
        String corpid = outerLinkGetOutLinkExtensionDTO.getCorpid();
        Integer businessType = outerLinkGetOutLinkExtensionDTO.getBusinessType();
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("type", OuterLinkTypeEnum.WRITE.getCode());
        params.put("del", 0);
        params.put("formId",formId);
        params.put("corpid",corpid);
        params.put("businessType",businessType);
        List<OuterLinkEntity> outerLinkEntityList = outerLinkModel.findEntitys(params);
        if(CollectionsUtil.isNotEmpty(outerLinkEntityList)){
            for (int i = 0; i < outerLinkEntityList.size(); i++) {
                OuterLinkEntity outerLinkEntity = outerLinkEntityList.get(i);
                if (StringUtil.isEmpty(outerLinkEntity.getExpandField())){
                    continue;
                }
                String token = outerLinkEntity.getHashCode();
                String url = proBaseConfig.getWebFrontUrl() + "outer-form.html#/" +token + "1";
                JSONObject extensionJSON = new JSONObject();
                extensionJSON.put("id",outerLinkEntity.getId());
                extensionJSON.put("field",outerLinkEntity.getExpandField());
                extensionJSON.put("url",url);
                extension.add(extensionJSON);
            }
        }
        outLinkExtensionGetVO.setExtension(extension);
        return outLinkExtensionGetVO;
    }

    /**
     * 高级设置获取
     * @param outerLinkAdvancedGetDTO
     * @return
     * @throws XbbException
     */
    @Override
    public OutLinkAdvancedGetVO getAdvanced(OuterLinkAdvancedGetDTO outerLinkAdvancedGetDTO) throws XbbException {
        OutLinkAdvancedGetVO outLinkAdvancedGetVO = new OutLinkAdvancedGetVO();
        Long formId = outerLinkAdvancedGetDTO.getFormId();
        String corpid = outerLinkAdvancedGetDTO.getCorpid();
        OuterLinkConfigEntity outerLinkConfigEntity = getOuterLinkConfigEntities(corpid,formId, OuterLinkTypeEnum.WRITE.getCode(),OutLinkSettingTypeEnum.ADVANCED_SETTING.getCode());
        JSONObject limit =new JSONObject();
        limit.put("enable",false);
        JSONObject  openCloseTime =new JSONObject();
        openCloseTime.put("enable",false);
        if (Objects.nonNull(outerLinkConfigEntity)){
            JSONObject jsonObject = outerLinkConfigEntity.getSeniorInfo();
            limit = jsonObject.getJSONObject("limit");
            openCloseTime = jsonObject.getJSONObject("openCloseTime");
        }
        outLinkAdvancedGetVO.setLimit(limit);
        outLinkAdvancedGetVO.setOpenCloseTime(openCloseTime);
        return outLinkAdvancedGetVO;
    }

    @Override
    public OutLinkDisplayGetVO displayGet(OuterLinkDisplayGetDTO outerLinkDisplayGetDTO) throws XbbException {
        OutLinkDisplayGetVO outLinkDisplayGetVO = new OutLinkDisplayGetVO();
        Integer businessType = outerLinkDisplayGetDTO.getBusinessType();
        String corpid = outerLinkDisplayGetDTO.getCorpid();
        Long formId = outerLinkDisplayGetDTO.getFormId();
        Integer type = outerLinkDisplayGetDTO.getType();
        List<OutLinkFieldAttrEntity> displayFields = new ArrayList<>();

        PaasFormEntity paasFormEntity = new PaasFormEntity();
        if ( Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode()) ) {
            //工单
            WorkOrderFormEntityExt workOrderFormEntityExt = workOrderFormModel.getByKey(formId, corpid);
            BeanUtil.copyProperties(workOrderFormEntityExt, paasFormEntity);
        } else {
            paasFormEntity = paasFormModel.getByKey(formId, corpid);
        }
        if ( paasFormEntity == null ) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }
        OuterLinkConfigEntity outerLinkConfigEntity = getOuterLinkConfigEntities(corpid, formId, OuterLinkTypeEnum.getByCode(type).getCode(),OutLinkSettingTypeEnum.DISPLAY_SETTING.getCode());
        List<FieldAttrEntity> filteredSpecialAttr = getOutLinkFieldList(corpid,formId,businessType, type, null);

        outLinkDisplayGetVO.setExplainList(filteredSpecialAttr);
        if (Objects.isNull(outerLinkConfigEntity)){
            outLinkDisplayGetVO.setFormName(paasFormEntity.getName());
            outLinkDisplayGetVO.setDefaultFormName(paasFormEntity.getName());
        } else {
            outLinkDisplayGetVO.setFormName(paasFormEntity.getName());
            outLinkDisplayGetVO.setDefaultFormName(outerLinkConfigEntity.getDefaultFormName());

            List<OutLinkFieldAttrEntity> list = JSONArray.parseArray(outerLinkConfigEntity.getExplains(),OutLinkFieldAttrEntity.class);
            for (int i = 0; i < list.size(); i++) {
                OutLinkFieldAttrEntity outLinkFieldAttrEntity = list.get(i);
                Integer renamed = outLinkFieldAttrEntity.getRenamed();

                if (Objects.equals(renamed,1)){
                    if (Objects.equals(outLinkFieldAttrEntity.getFieldType(), FieldTypeEnum.SUB_FORM.getType())
                            || Objects.equals(outLinkFieldAttrEntity.getFieldType(), FieldTypeEnum.CONTACT_NUMBER.getType())) {
                        // 子表单
                        List<? extends OutLinkFieldAttrEntity> subExplainList = outLinkFieldAttrEntity.getSubForm().getItems();
                        List<OutLinkFieldAttrEntity> subFormFieldAttrList = new ArrayList<>();
                        if (Objects.nonNull(subExplainList)) {
                            subExplainList.forEach(item -> {
                                if (Objects.equals(item.getRenamed(),1)){
                                    subFormFieldAttrList.add(item);
                                }
                            });
                        }
                        OutLinkSubFormPojo subFormPoJo = new OutLinkSubFormPojo();
                        subFormPoJo.setItems(subFormFieldAttrList);
                        outLinkFieldAttrEntity.setSubForm(subFormPoJo);
                    }
                    displayFields.add(outLinkFieldAttrEntity);
                }
            }
        }
        outLinkDisplayGetVO.setDisplayFields(displayFields);
        return outLinkDisplayGetVO;
    }


    /**
     * 获取外链设置
     * @param corpid
     * @param formId
     * @param type
     * @param configType
     * @return
     * @throws XbbException
     */
    @Override
    public OuterLinkConfigEntity getOuterLinkConfigEntities(String corpid, Long formId, Integer type, Integer configType) throws XbbException {
        Map<String,Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("type", type);
        params.put("corpid",corpid);
        params.put("del", DelEnum.NORMAL.getDel());
        params.put("formId",formId);
        params.put("configType", configType);
        List<OuterLinkConfigEntity>  entityList = outerLinkConfigModel.findEntitys(params);
        if (CollectionsUtil.isNotEmpty(entityList)){
            return entityList.get(0);
        }
        return null;
    }

    public List<OuterLinkEntity> getOuterLinkEntities (String corpid, Long formId, Integer type, Long dataId,String extenedField,Integer del) throws XbbException {
        Map<String,Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("corpid",corpid);
        params.put("del",del);
        params.put("formId",formId);
        params.put("type", type);
        params.put("dataId", dataId);
        params.put("expandField",extenedField);
        List<OuterLinkEntity>  entityList = outerLinkModel.findEntitys(params);
        if (CollectionsUtil.isNotEmpty(entityList)){
            return entityList;
        }
        return null;
    }

    public List<OuterLinkEntity> getOuterLinkEntitiesExcludeExpandField (String corpid, Long formId, Integer type, Long dataId,String extenedField) throws XbbException {
        Map<String,Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("corpid",corpid);
        params.put("del", DelEnum.NORMAL.getDel());
        params.put("formId",formId);
        params.put("type", type);
        params.put("dataId", dataId);
        params.put("excludeExpandField","excludeExpandField");
        List<OuterLinkEntity>  entityList = outerLinkModel.findEntitys(params);
        if (CollectionsUtil.isNotEmpty(entityList)){
            return entityList;
        }
        return null;
    }

    /**
     * 获取外链筛选项设置
     * @param outerLinkFilterGetDTO
     * @return
     * @throws XbbException
     */
    @Override
    public OutLinkFilterGetVO filterGet(OuterLinkFilterGetDTO outerLinkFilterGetDTO) throws XbbException {
        OutLinkFilterGetVO outLinkFilterGetVO = new OutLinkFilterGetVO();
        List<String> screen = new ArrayList<>();

        Integer businessType = outerLinkFilterGetDTO.getBusinessType();
        Long formId = outerLinkFilterGetDTO.getFormId();
        String corpid = outerLinkFilterGetDTO.getCorpid();
        List<FieldAttrEntity> filteredSpecialAttr = getOutLinkFieldList(corpid,formId,businessType,OuterLinkTypeEnum.SEARCH.getCode(),BasicConstant.ONE);
        List<String> attrList = OuterLinkFilterRemoveAttrEnum.getAttrList(businessType);
        if (CollectionsUtil.isNotEmpty(attrList)) {
            filteredSpecialAttr.removeIf(item -> attrList.contains(item.getAttr()));
        }
        OuterLinkConfigEntity outerLinkConfigEntity = getOuterLinkConfigEntities(corpid,formId, OuterLinkTypeEnum.SEARCH.getCode(),OutLinkSettingTypeEnum.FILTER_SETTING.getCode());
        if (Objects.isNull(outerLinkConfigEntity)){
            for (int i = 0; i < filteredSpecialAttr.size(); i++) {
                screen.add(filteredSpecialAttr.get(i).getAttr());
            }

        } else {
            List<OutLinkFieldAttrEntity> list = JSONArray.parseArray(outerLinkConfigEntity.getExplains(),OutLinkFieldAttrEntity.class);
            list = syncOuterLinkField(filteredSpecialAttr,list, OuterLinkTypeEnum.SEARCH,OutLinkSettingTypeEnum.FILTER_SETTING);
            for (int i = 0; i < list.size(); i++) {
                if (Objects.equals(list.get(i).getFilterable(),1)){
                    screen.add(list.get(i).getAttr());
                }
            }
        }
        outLinkFilterGetVO.setFormExplainList(filteredSpecialAttr);
        outLinkFilterGetVO.setScreen(screen);
        return outLinkFilterGetVO;
    }

    /**
     * 拿外链的解释
     * @param corpid
     * @param formId
     * @param businessType
     * @param fromFilter
     * @return
     * @throws XbbException
     */
    public List<FieldAttrEntity> getOutLinkFieldList(String corpid, Long formId, Integer businessType, Integer type, Integer fromFilter) throws XbbException{
        PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
        if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
            //工单
            WorkOrderExplainEntity workOrderExplainEntity = workOrderExplainModel.getByFormId(formId, corpid);
            if (Objects.isNull(workOrderExplainEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            BeanUtil.copyProperties(workOrderExplainEntity, paasFormExplainEntity);
        } else {
            //其他
            paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
            if (Objects.isNull(paasFormExplainEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
        }
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        if (Objects.equals(type, OuterLinkTypeEnum.SEARCH.getCode()) && Objects.equals(fromFilter, BasicConstant.ONE)) {
            // 外链筛选仅支持单行文本、数字、日期、单选按钮、下拉框、地址、流水号、标签
            explainList.removeIf(item -> !FILTER_ATTR.contains(item.getFieldType()));
            explainList.removeIf(item -> !ShowTypeEnum.listShow(item.getShowType()));
            explainList.removeIf(item -> Objects.equals("extensionField",item.getSaasAttr()));
            explainList.removeIf(item -> Objects.equals(item.getIsOpen(), 2));
            return explainList;
        }
        ExplainUtil.filterSpecialAttr(explainList, type, null);
        OuterLinkTypeEnum typeEnum = OuterLinkTypeEnum.getByCode(type);
        switch (typeEnum) {
            case SEARCH:
                List<String> searchRemoveAttr = OuterLinkFilterRemoveAttrEnum.getAttrList(businessType);
                explainList.removeIf(item -> searchRemoveAttr.contains(item.getAttr()));
                break;
            case SHARE:
                List<String> shareRemoveAttr = OuterLinkShareRemoveAttrEnum.getAttrList(businessType);
                explainList.removeIf(item -> shareRemoveAttr.contains(item.getAttr()));
                break;
            case WRITE:
                List<String> addRemoveAttr = OuterLinkAddRemoveAttrEnum.getAttrList(businessType);
                explainList.removeIf(item -> addRemoveAttr.contains(item.getAttr()));
                break;
            default:
                break;
        }
        return explainList;
    }
}
